<?php
/**
 * Created by PhpStorm.
 * User: zhongbaitong
 * Date: 2020/1/10
 * Time: 14:20
 */

namespace app\common\controller;

use app\common\exception\ApiError;
use app\user\model\User;

/**
 * 框架公共控制器
 * @package app\common\controller
 */
class ApiBase extends Base
{

    /**
     * @throws ApiError
     * @throws \app\common\exception\ApiException
     */
    public function initialize()
    {
        parent::initialize();
        $this->user = $this->getUserInfo();
    }

    // get user info ..
    public function getUserInfo()
    {
        $token = $this->request->param("token") ?: null;
        $str = str_decrypt($token, md5(config('wechat.token_yan')));
        $arr = explode('/', $str);
        return User::get($arr[0]);
    }

    // 获取已授权的用户ID
    // 否则当作游客处理..
    public function getAuthorizeUID()
    {
        return $this->user["is_authorize"] == 1 ? $this->user["id"] : 0;
    }

    /**
     * check login status ..
     * (一般作前置方法)
     * @throws ApiError
     */
    public function checkIsLogin()
    {
        if (intval($this->getAuthorizeUID()) <= 0)
            throw new ApiError("未登录！");

        return true;
    }

    /**
     * get request params ..
     * @param  mixed $must
     * @return mixed
     * @throws ApiError
     */
    public function getInput($must = "",$is_get_user_id = false)
    {
        $input = $this->request->param();
        if ($must) {
            if (is_string($must)) {
                $must = explode(',', $must);
            }

            if (is_array($must)) {
                foreach ($must as $k => $v) {
                    if (!isset($input[$v])) {
                        throw new ApiError($v . " 参数必须", 0);
                    }
                }
            }
        }
        $is_get_user_id && $input["user_id"] = $this->getAuthorizeUID();
        return $input;
    }


    /**
     * success to response data ..
     * @param string $msg
     * @param array $extra
     * @param int $code
     * @return \think\response\Json
     */
    protected function apiSuccess($msg = "", $extra = [], $code = 1)
    {
        $data = [
            'code' => $code,
            'msg' => $msg ?: "操作成功！",
        ];
        if (is_array($extra)) {
            $data = array_merge($data, (array)$extra);
        }
        return $this->apiReturn($data);
    }

    /**
     * fail to response data ..
     * @param string $msg
     * @param array $extra
     * @param int $code
     * @return \think\response\Json
     */
    protected function apiError($msg = "", $extra = [], $code = 0)
    {
        $data = [
            'code' => $code,
            'msg' => $msg ?: "操作失败！",
        ];
        if (is_array($extra)) {
            $data = array_merge($data, (array)$extra);
        }

        return $this->apiReturn($data);
    }

    /**
     * response data ..
     * @param array $params
     * @return \think\response\Json
     */
    protected function apiReturn($params = [])
    {
        $SUCCESS_CODE = 1;
        $FAILED_CODE = 0;
        $result = ['code' => $FAILED_CODE, 'msg' => '(' . __LINE__ . ')' . "操作失败",];

        if (is_string($params)) {
            $result = ['code' => $FAILED_CODE, 'msg' => $params];
        }

        if (is_numeric($params)) {
            $result = ['status' => $params > 0 ? $SUCCESS_CODE : $FAILED_CODE, 'result' => $params > 0 ? "操作成功！": "操作失败", 'data' => $params];
        }

        if (is_bool($params)) {
            $result = ['status' => $params == true ? $SUCCESS_CODE : $FAILED_CODE, 'result' => $params == true ? "操作成功！" : "操作失败"];
        }

        if (is_array($params)) {
            if (isset($params['code']) && isset($params['msg'])) {
                $result = $params;
            } else if (count($params)) {
                $result = array_merge(['code' => $SUCCESS_CODE, 'msg' => "操作成功！"], $params);
            } else {
                $result = ['code' => $FAILED_CODE, 'msg' => "操作成功！"];
            }
        }

        return json($result);
    }


    /**
     * to upload source ..
     * @param string $dir 存放目录
     * @param int $type 上传类型：1-图片 2-视频 3-音频
     * @param array $extra 扩充参数
     * @return string
     * @throws ApiError
     */
    public function _upload($from = "default", $type = 1, $extra = [])
    {
        $root_path = ROOT_PATH . "/public";                     // root/public 路径
        $service_url = $this->request->domain();      // 域名地址
        $oss_url = config("api_cos.mmUrl");           // 云地址

        // 类型校验
        $exts = [
            1 => 'jpg,gif,png,bmp,jpeg,JPG',
            2 => "mp4,mov,rmvb,avi",
            3 => "avi,mkv,ogg,avi,rm,rmvb,flv,mpg,mov,mkv,aac,m4a,wav"
        ];

        $validate = [
            'size' => $extra['size'] ?? 102400,
            'ext' => $extra['ext'] ?? $exts[$type]
        ];

        // 上传
        if ($file = $this->request->file('file')) {
            // 文件存放目录
            $dir = 'upload/' . $from . date('/Y/m/d/');
            // 绝对路径
            $save_dir = $root_path . $dir;
            // 相对路径
            $relative_dir = ROOT_DIR . $dir;

            !is_dir($save_dir) && mkdir(iconv("UTF-8", "GBK", $save_dir), 0777, true);
            // 执行上传
            $info = $file->rule('uniqid')->validate($validate)->move($save_dir);

            if ($info) {
                // 绝对路径
                $save_path = $save_dir . $info->getSaveName();
                // 相对路径
                $relative_path = $relative_dir . str_replace('\\', '/', $info->getSaveName());

                // 图片处理
                if ($type == 1) {
                    // 压缩（默认开启）
                    $is_thumb = $extra["is_thumb"] ?? true;
                    if ($is_thumb) {
                        $width = $extra["width"] ?? 1024;
                        $height = $extra["height"] ?? 1024;
                        $thumb_type = $extra["thumb_type"] ?? 1;
                        \think\Image::open($save_path)->thumb($width, $height, $thumb_type)->save($save_path);
                    }

                    // 加图片水印（默认关闭）
                    $is_water = $extra["is_water"] ?? false;
                    if ($is_water) {
                        // logo图路径
                        $logo_img = $extra["is_water"] ?? $root_path . 'static/logo.png';
                        // 自适应大小
                        $image = \think\Image::open($save_path);
                        $logo_width = $image->width() / 4;
                        $logo_height = $image->height() / 4;

                        $temp_logo = $root_path . 'static/temp_' . uniqid() . '.png';
                        \think\Image::open($logo_img)->thumb($logo_width, $logo_height, 1, 1)->save($temp_logo);

                        // 上水印
                        $image->water($temp_logo, 9, 50)->save($save_path);
                        // 销毁临时水印
                        file_exists($temp_logo) && unlink($temp_logo);
                    }
                }
                // 视频处理（默认关闭，开启时确保服务器已安装 ffmpeg）
                if ($type == 2) {
                    // 视频压缩
                    $is_thumb = $extra["is_thumb"] ?? false;
                    if ($is_thumb) {
                        $set_thumb = "ffmpeg -threads 2 -i $save_path -b 1000k $save_path" . ".mp4";
                        exec($set_thumb);
                        unlink($save_path);
                        rename($save_path . ".mp4", $save_path);
                    }

                    // 视频截图（默认关闭，开启时确保服务器已安装 ffmpeg）
                    $is_crop = $extra["is_crop"] ?? false;
                    if ($is_crop) {
                        $get_cover = "ffmpeg -i " . $save_path . " -r 1 -ss 00:00:01 -vframes 1 " . $save_path . ".jpeg";
                        exec($get_cover);
                    }
                }

                // 上传到云储存服务器（开启时确保已搭建云储存服务器）
                $is_up_to_cos = $extra["is_cos"] ?? false;
                $rs = [];
                if ($is_up_to_cos)
                    $rs = up_to_cos($relative_path, file_get_contents($service_url . $relative_path));

                $url_path = $rs ? $oss_url . $relative_path : $service_url . $relative_path;

                return compact("type", "url_path", "relative_path");
            } else {
                // 上传失败获取错误信息
                throw new ApiError($file->getError(), 47002);
            }
        } else {
            throw new ApiError("file " . "参数错误", 47001);
        }
    }

    // api is not exist ..
    public function _empty()
    {
        return json('接口不存在!');
    }
}
